package biz.datalk.industrialland.admin.modules.online.dynform.service.impl;

import biz.datalk.commons.helper.collection.FixMapHelper;
import biz.datalk.commons.helper.collection.ListHelper;
import biz.datalk.commons.utils.BasicParserUtils;
import biz.datalk.commons.utils.IdProvider;
import biz.datalk.commons.utils.json.JsonUtil;
import biz.datalk.industrialland.admin.modules.common.servie.ICommonService;
import biz.datalk.industrialland.admin.modules.online.config.cfg.DynformConstant;
import biz.datalk.industrialland.admin.modules.online.config.model.ColumnVo;
import biz.datalk.industrialland.admin.modules.online.config.util.DbTableUtil;
import biz.datalk.industrialland.admin.modules.online.config.util.DynfromButtonUtil;
import biz.datalk.industrialland.admin.modules.online.config.util.HookUtil;
import biz.datalk.industrialland.admin.modules.online.dynform.mapper.IDynformFieldMapper;
import biz.datalk.industrialland.admin.modules.online.dynform.mapper.IDynformHeadExtMapper;
import biz.datalk.industrialland.admin.modules.online.dynform.mapper.IDynformHeadMapper;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.dto.DictItem;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.dto.DynformFieldDTO;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.dto.DynformHeadDTO;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.po.DynformField;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.po.DynformFieldExample;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.po.DynformHead;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.po.DynformHeadExample;
import biz.datalk.industrialland.admin.modules.online.dynform.service.IDynformServices;
import biz.datalk.industrialland.admin.modules.util.ShiroUtil;
import biz.datalk.industrialland.common.def.enums.DBYNEnum;
import biz.datalk.industrialland.common.exception.ServiceException;
import biz.datalk.industrialland.common.result.UnifyResult;
import biz.datalk.industrialland.common.result.UnifyResultUtil;
import biz.datalk.industrialland.common.util.I18NUtil;
import biz.datalk.industrialland.common.util.RedisUtil;
import biz.datalk.industrialland.common.validated.Insert;
import biz.datalk.industrialland.common.validated.Update;
import biz.datalk.industrialland.common.validated.ValidateHelper;
import biz.datalk.industrialland.mbg.pojo.po.SysUser;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.groups.Default;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author tarofang@163.com
 * @date 2019-12-17
 */
@Slf4j
@Service
public class DynformServicesImpl implements IDynformServices {

    private final IDynformHeadMapper dynformHeadMapper;
    private final IDynformHeadExtMapper dynformHeadExtMapper;

    private final IDynformFieldMapper dynformFieldMapper;

    private final ValidateHelper validateHelper;

    private ICommonService commonService;
    private RedisUtil redisUtil;

    @Autowired
    public DynformServicesImpl(IDynformHeadMapper dynformHeadMapper, IDynformHeadExtMapper dynformHeadExtMapper, IDynformFieldMapper dynformFieldMapper, ValidateHelper validateHelper) {
        this.dynformHeadMapper = dynformHeadMapper;
        this.dynformHeadExtMapper = dynformHeadExtMapper;
        this.dynformFieldMapper = dynformFieldMapper;
        this.validateHelper = validateHelper;
    }

    @Autowired
    @Qualifier("commonService")
    public void setCommonService(ICommonService commonService) {
        this.commonService = commonService;
    }

    @Autowired
    @Qualifier("redisUtil")
    public void setRedisUtil(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    @Override
    public UnifyResult list(DynformHeadDTO dynformHeadDTO) {

        DynformHeadExample example = new DynformHeadExample();
        example.setOrderByClause("update_time DESC");

        DynformHeadExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(dynformHeadDTO.getTableName())) {
            criteria.andTableNameLike("%" + dynformHeadDTO.getTableName() + "%");
        }
        if (StringUtils.isNotBlank(dynformHeadDTO.getIsDbsynch())) {
            criteria.andIsDbsynchEqualTo(dynformHeadDTO.getIsDbsynch());
        }

        PageHelper.startPage(dynformHeadDTO.getPageNumber(), dynformHeadDTO.getPageSize());
        List<DynformHead> dynformHeads = dynformHeadMapper.selectByExample(example);
        PageInfo<DynformHead> pageInfo = new PageInfo<>(dynformHeads);
        return UnifyResult.success().mapData().put("rows", pageInfo.getList()).put("total", pageInfo.getTotal());
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public UnifyResult addHead(DynformHeadDTO dynformHeadDTO) {
        String tableName = StringUtils.trimToEmpty(dynformHeadDTO.getTableName());
        DynformHead exists = selectByTableName(tableName);
        if (exists != null) {
            return UnifyResult.fail(I18NUtil.getMsg("dynform.head.exists.tablename"));
        }

        // 字段验证
        UnifyResult result = checkTableFields(dynformHeadDTO, Insert.class);
        if (UnifyResultUtil.isFail(result)) {
            return result;
        }
        @SuppressWarnings("unchecked") List<DynformFieldDTO> fieldList = (List<DynformFieldDTO>) result.getData();

        // dynform_head 表新增数据
        dynformHeadDTO.setId(IdProvider.createUUIDId());
        dynformHeadDTO.setDynformVersion("1");
        dynformHeadMapper.insertSelective(dynformHeadDTO);

        // dynform_field 表新增数据
        int fieldOrder = 1;
        for (DynformFieldDTO dynformFieldDTO : fieldList) {
            dynformFieldDTO.setId(IdProvider.createUUIDId());
            dynformFieldDTO.setTableId(dynformHeadDTO.getId());
            //字段排序修正
            dynformFieldDTO.setFieldOrder(fieldOrder);
            // 保存数据
            dynformFieldMapper.insertSelective(dynformFieldDTO);
            fieldOrder++;
        }

        return UnifyResult.success();
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public UnifyResult editHead(DynformHeadDTO dynformHeadDTO) {
        DynformHead exists = dynformHeadMapper.selectByPrimaryKey(dynformHeadDTO.getId());
        if (exists == null) {
            return UnifyResult.fail(I18NUtil.getMsg("dynform.head.no.exists.or.delete"));
        }

        String hookImplClass = StringUtils.trimToEmpty(dynformHeadDTO.getHookImplClass());
        if (StringUtils.isNotBlank(hookImplClass)) {
            if (!HookUtil.isExistsImplClass(hookImplClass)) {
                return UnifyResult.fail(I18NUtil.getMsg("message.dynform.no.exists.hookImplClass", hookImplClass));
            }
        }

        // 如果已同步 不允许变更表名
        if (StringUtils.equals(exists.getIsDbsynch(), DBYNEnum.Y.name())) {
            if (!StringUtils.equals(dynformHeadDTO.getTableName(), exists.getTableName())) {
                return UnifyResult.fail(I18NUtil.getMsg("dynform.head.has.sync.cant.change.tablename"));
            }
        }

        // 字段验证
        UnifyResult result = checkTableFields(dynformHeadDTO, Update.class);
        if (UnifyResultUtil.isFail(result)) {
            return result;
        }
        @SuppressWarnings("unchecked") List<DynformFieldDTO> fieldList = (List<DynformFieldDTO>) result.getData();

        // 前端传入的参数字段 按照 fieldOrder 升序排列 【降序 => fieldList.sort(Comparator.comparingInt(DynformField::getFieldOrder).reversed());】
        fieldList.sort(Comparator.comparingInt(DynformField::getFieldOrder));
        // 重新设置顺序 保证 fieldOrder 的连续性
        for (int idx = 0, size = fieldList.size(); idx < size; idx++) {
            fieldList.get(idx).setFieldOrder(idx + 1);
        }


        // 获取以存在的字段
        List<DynformFieldDTO> existsFields = getExistsFields(exists.getId());

        // 区分字段的新增、删除、更新
        Map<String, List<DynformFieldDTO>> diffOperateMap = diffFields(fieldList, existsFields, exists.getId());

        // 保存字段信息
        saveTableFields(diffOperateMap);

        // 处理表信息
        exists.setIsDbsynch(tableIsSync(exists, diffOperateMap) ? DBYNEnum.Y.name() : DBYNEnum.N.name());
        exists.setIsCheckbox(dynformHeadDTO.getIsCheckbox());
        exists.setIsPagination(dynformHeadDTO.getIsPagination());
        exists.setTableComment(dynformHeadDTO.getTableComment());
        exists.setTableType(dynformHeadDTO.getTableType());
        exists.setHookImplClass(hookImplClass);
        exists.setTableDefBtns(dynformHeadDTO.getTableDefBtns());

        // 版本号 +1
        int version = BasicParserUtils.parseInt(exists.getDynformVersion(), 1);
        exists.setDynformVersion(String.valueOf(version + 1));
        dynformHeadMapper.updateByPrimaryKey(exists);

        return UnifyResult.success();
    }

    private boolean tableIsSync(DynformHead exists, Map<String, List<DynformFieldDTO>> diffOperateMap) {
        if (!StringUtils.equals(exists.getIsDbsynch(), DBYNEnum.Y.name())) {
            return false;
        }

        List<DynformFieldDTO> addFields = diffOperateMap.get(DynformConstant.ADD_FIELDS_KEY);
        List<DynformFieldDTO> editFields = diffOperateMap.get(DynformConstant.EDIT_FIELDS_KEY);
        List<DynformFieldDTO> deleteFields = diffOperateMap.get(DynformConstant.DELETE_FIELDS_KEY);
        if (CollectionUtils.isNotEmpty(addFields) || CollectionUtils.isNotEmpty(deleteFields)) {
            return false;
        }
        if (CollectionUtils.isNotEmpty(editFields)) {
            for (DynformFieldDTO field : editFields) {
                if (StringUtils.isNotEmpty(field.getOldFieldName()) && !StringUtils.equals(field.getOldFieldName(), field.getFieldName())) {
                    return false;
                }
            }
        }
        return true;
    }

    private void saveTableFields(Map<String, List<DynformFieldDTO>> diffOperateMap) {
        List<DynformFieldDTO> addFields = diffOperateMap.get(DynformConstant.ADD_FIELDS_KEY);
        List<DynformFieldDTO> editFields = diffOperateMap.get(DynformConstant.EDIT_FIELDS_KEY);
        List<DynformFieldDTO> deleteFields = diffOperateMap.get(DynformConstant.DELETE_FIELDS_KEY);

        if (CollectionUtils.isNotEmpty(addFields)) {
            for (DynformFieldDTO field : addFields) {
                dynformFieldMapper.insertSelective(field);
            }
        }
        if (CollectionUtils.isNotEmpty(editFields)) {
            for (DynformFieldDTO field : editFields) {
                dynformFieldMapper.updateByPrimaryKeySelective(field);
            }
        }
        if (CollectionUtils.isNotEmpty(deleteFields)) {
            List<String> ids = ListHelper.create().getValList(deleteFields, "getId", DynformFieldDTO.class, String.class);
            DynformFieldExample example = new DynformFieldExample();
            example.createCriteria().andIdIn(ids);
            dynformFieldMapper.deleteByExample(example);
        }
    }

    private Map<String, List<DynformFieldDTO>> diffFields(List<DynformFieldDTO> fieldList, List<DynformFieldDTO> existsFields, String tableId) {
        // 区分字段的新增、删除、更新
        List<DynformFieldDTO> addFields = new ArrayList<>();
        List<DynformFieldDTO> editFields = new ArrayList<>();
        DynformFieldDTO existsField;
        for (DynformFieldDTO dynformFieldDTO : fieldList) {
            // 根据 ID 查询
            existsField = findExistsById(dynformFieldDTO.getId(), existsFields);
            // 根据 fieldName 查询
            if (existsField == null) {
                existsField = findExistsByFieldName(dynformFieldDTO.getFieldName(), existsFields);
            }

            dynformFieldDTO.setTableId(tableId);

            if (existsField == null) {
                dynformFieldDTO.setId(IdProvider.createUUIDId());
                addFields.add(dynformFieldDTO);
            } else {
                dynformFieldDTO.setId(existsField.getId());
                dynformFieldDTO.setCreateTime(existsField.getCreateTime());
                dynformFieldDTO.setCreateBy(existsField.getCreateBy());
                dynformFieldDTO.setCreateName(existsField.getCreateName());
                dynformFieldDTO.setOldFieldName(existsField.getFieldName());
                editFields.add(dynformFieldDTO);
            }
        }
        List<DynformFieldDTO> deleteFields = new ArrayList<>();
        for (DynformFieldDTO existField : existsFields) {
            existsField = findExistsById(existField.getId(), editFields);
            if (existsField == null) {
                deleteFields.add(existField);
            }
        }

        Map<String, List<DynformFieldDTO>> diffOperateMap = new HashMap<>(4);
        diffOperateMap.put(DynformConstant.ADD_FIELDS_KEY, addFields);
        diffOperateMap.put(DynformConstant.EDIT_FIELDS_KEY, editFields);
        diffOperateMap.put(DynformConstant.DELETE_FIELDS_KEY, deleteFields);

        return diffOperateMap;
    }

    private DynformFieldDTO findExistsByFieldName(String fieldName, List<DynformFieldDTO> existsFields) {
        if (CollectionUtils.isEmpty(existsFields)) {
            return null;
        }
        for (DynformFieldDTO existsField : existsFields) {
            if (StringUtils.equals(fieldName, existsField.getFieldName())) {
                return existsField;
            }
        }
        return null;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public UnifyResult delHead(DynformHeadDTO dynformHeadDTO) {
        String id = dynformHeadDTO.getId();
        if (StringUtils.isBlank(id)) {
            return UnifyResult.fail(I18NUtil.getMsg("dynform.head.no.exists.or.delete"));
        }

        DynformHead exists = dynformHeadMapper.selectByPrimaryKey(id);
        if (exists == null) {
            return UnifyResult.fail(I18NUtil.getMsg("dynform.head.no.exists.or.delete"));
        }

        // TODO 删除表
        // dynformHeadMapper.deleteByPrimaryKey(id);


        return UnifyResult.success();
    }

    @Override
    public UnifyResult headDetail(DynformHeadDTO dynformHeadDTO) {
        DynformHead exists = dynformHeadMapper.selectByPrimaryKey(dynformHeadDTO.getId());
        if (exists == null) {
            return UnifyResult.fail(I18NUtil.getMsg("dynform.head.no.exists.or.delete"));
        }

        DynformFieldExample example = new DynformFieldExample();
        example.setOrderByClause("field_order ASC");
        example.createCriteria().andTableIdEqualTo(exists.getId());
        List<DynformField> dynformFields = dynformFieldMapper.selectByExample(example);
        dynformFields = CollectionUtils.isEmpty(dynformFields) ? Collections.emptyList() : dynformFields;

        FixMapHelper fixMapHelper = FixMapHelper.create();
        fixMapHelper.put("head", exists);
        fixMapHelper.put("fields", dynformFields);

        return UnifyResult.success().setData(fixMapHelper.asMap());
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public UnifyResult doDbSync(DynformHeadDTO dynformHeadDTO) {
        String tableId = StringUtils.trimToEmpty(dynformHeadDTO.getId());
        if (StringUtils.isEmpty(tableId)) {
            return UnifyResult.fail(I18NUtil.getMsg("dynform.head.no.exists.or.delete"));
        }

        DynformHead exists = dynformHeadMapper.selectByPrimaryKey(tableId);
        if (exists == null) {
            return UnifyResult.fail(I18NUtil.getMsg("dynform.head.no.exists.or.delete"));
        }
        // 获取字段
        DynformFieldExample example = new DynformFieldExample();
        example.setOrderByClause("field_order ASC");
        example.createCriteria().andTableIdEqualTo(tableId);
        List<DynformField> dynformFields = dynformFieldMapper.selectByExample(example);


        try {
            DbTableUtil.getDatabaseType();
        } catch (Exception ex) {

        }

        // String tableName = exists.getTableName();
        // boolean tabExists = commonService.judgeTableIsExit(tableName);
        // if (!tabExists) {
        //     // 新建表
        //     commonService.createTable(exists, dynformFields);
        // }
        // // 更新表


        return UnifyResult.success();
    }

    @Override
    public DynformHead selectByPk(String tId) {
        return dynformHeadMapper.selectByPrimaryKey(tId);
    }

    @Override
    public List<DynformFieldDTO> selectByTableId(String tableId) {
        return getExistsFields(tableId);
    }

    @Override
    public List<DynformFieldDTO> selectByTableId(String tableId, boolean includeFieldDict) {
        List<DynformFieldDTO> existsFields = getExistsFields(tableId);
        if (!includeFieldDict) {
            return existsFields;
        }

        for (DynformFieldDTO field : existsFields) {
            String dictTable = StringUtils.trimToEmpty(field.getDictTable());
            String dictCode = StringUtils.trimToEmpty(field.getDictCode());
            String dictText = StringUtils.trimToEmpty(field.getDictText());
            // 从 sys_dict sys_dict_item 表中获取数据
            if (StringUtils.isNotEmpty(dictCode) && StringUtils.isAllEmpty(dictTable, dictText)) {
                List<DictItem> dicts = commonService.selectDictFromSysdict(dictCode);
                if (CollectionUtils.isNotEmpty(dicts)) {
                    field.setDicts(dicts);
                }
                continue;
            }
            // 从 {dictTable} 表中获取数据
            if (StringUtils.isNotEmpty(dictTable) && StringUtils.isNotEmpty(dictCode) && StringUtils.isNotEmpty(dictText)) {
                List<DictItem> dicts = commonService.selectDictFromCustomTable(dictTable, dictCode, dictText);
                if (CollectionUtils.isNotEmpty(dicts)) {
                    field.setDicts(dicts);
                }
                continue;
            }
        }

        return existsFields;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public UnifyResult remove(DynformHeadDTO dynformHeadDTO) {
        DynformHead exists = dynformHeadMapper.selectByPrimaryKey(dynformHeadDTO.getId());
        if (exists == null) {
            return UnifyResult.fail(I18NUtil.getMsg("dynform.head.no.exists.or.delete"));
        }

        int resInt = dynformHeadMapper.deleteByPrimaryKey(dynformHeadDTO.getId().trim());
        if (resInt != 1) {
            throw new ServiceException("remove fail");
        }

        DynformFieldExample example = new DynformFieldExample();
        DynformFieldExample.Criteria criteria = example.createCriteria();
        criteria.andTableIdEqualTo(exists.getId());
        List<DynformField> dynformFields = dynformFieldMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(dynformFields)) {
            resInt = dynformFieldMapper.deleteByExample(example);
            if (resInt <= 0) {
                throw new ServiceException("remove fail");
            }
        }

        return UnifyResult.success();
    }

    @Override
    public UnifyResult queryTables() {
        // TODO 判定访问权限

        List<String> list = null;
        try {
            list = DbTableUtil.readDBAllTableName();
        } catch (Exception ex) {
            log.warn(ex.getMessage(), ex);
            return UnifyResult.fail("同步失败，未获取数据库表信息");
        }

        // 排序
        list.sort(String::compareTo);

        // 获取 dynform_head 中管理的表
        List<String> manageTableNames = dynformHeadExtMapper.selectAllTableNames();
        list.removeAll(manageTableNames);

        // 获取需要排除的表的指标
        // String[] tableNamePrefixArr = StringUtils.splitByWholeSeparatorPreserveAllTokens(redisUtil.getStr(DynformConstant.SYS_CFG_EXCLUDE_TABLE_NAME_PREFIX), DynformConstant.TABLE_NAME_SEPERATOR);
        String[] tableNamePrefixArr = biz.datalk.commons.utils.StringUtils.splitAndTrim(redisUtil.getStr(DynformConstant.SYS_CFG_EXCLUDE_TABLE_NAME_PREFIX), DynformConstant.TABLE_NAME_SEPERATOR);

        List<Map<String, Object>> resMapList = new ArrayList<>();
        for (String tableName : list) {
            // 排除 指定开头的表 或者 指定表
            if (excludeTableName(tableName, tableNamePrefixArr)) {
                continue;
            }
            resMapList.add(FixMapHelper.create().put("id", tableName).asMap());
        }

        return UnifyResult.success().setData(resMapList);
    }

    @Override
    public UnifyResult importFromDB(Map<String, String> params) {
        String tableNames = StringUtils.trimToEmpty(params.get("tableNames"));
        if (StringUtils.isEmpty(tableNames)) {
            return UnifyResult.fail("请指定需要导入的表名");
        }

        String[] tables = biz.datalk.commons.utils.StringUtils.splitAndTrim(tableNames, ",");
        if (ArrayUtils.isEmpty(tables)) {
            return UnifyResult.fail("请指定需要导入的表名");
        }

        Map<String, UnifyResult> resMap = new HashMap<>();
        UnifyResult result = null;
        for (String table : tables) {
            result = saveDBTable2DynfromHead(table);
            resMap.put(table, result);
        }

        return UnifyResult.success();
    }

    private UnifyResult saveDBTable2DynfromHead(String tableName) {
        if (StringUtils.isBlank(tableName)) {
            return UnifyResult.fail("需要导入的表名不存在");
        }

        tableName = tableName.trim();
        DynformHeadExample example = new DynformHeadExample();
        example.createCriteria().andTableNameEqualTo(tableName);
        long count = dynformHeadMapper.countByExample(example);
        if (count > 0) {
            return UnifyResult.fail(String.format("需要导入的表【%s】已在管理中", tableName));
        }

        SysUser currentUser = ShiroUtil.currentSysUser();

        // 获取列
        List<ColumnVo> columnVos = DbTableUtil.getTableColumns(tableName);
        List<ColumnVo> pks = columnVos.stream().filter(vo -> StringUtils.equals(vo.getFieldIsPk(), DBYNEnum.Y.name())).collect(Collectors.toList());
        if (CollectionUtils.size(pks) == 0) {
            return UnifyResult.fail(String.format("需要导入的表【%s】未设置主键", tableName));
        }
        if (CollectionUtils.size(pks) > 1) {
            return UnifyResult.fail(String.format("需要导入的表【%s】设置主键数大于1", tableName));
        }



        Date now = new Date();

        DynformHead head = new DynformHead();
        head.setId(IdProvider.createUUIDId());
        head.setCreateBy(String.valueOf(currentUser.getId()));
        head.setCreateName(currentUser.getUsername());
        head.setCreateTime(now);
        //head.setSysOrgCode("");
        head.setIsValid(DBYNEnum.Y.name());
        head.setIsDelete(DBYNEnum.N.name());
        head.setIsCheckbox(DBYNEnum.Y.name());
        head.setIsDbsynch(DBYNEnum.Y.name());
        head.setIsPagination(DBYNEnum.Y.name());
        head.setIsTree(DBYNEnum.N.name());
        head.setDynformPkType("UUID");
        head.setDynformVersion("1");
        head.setTableName(tableName);
        head.setTableComment(tableName);
        head.setTableType(0);
        head.setHookImplClass("");
        head.setTableDefBtns(DynfromButtonUtil.DEFAULT_ALL_BTN_CODE);

        List<DynformField> fields = new ArrayList<>();
        String fieldJavaType;
        for (ColumnVo vo : columnVos) {
            fieldJavaType = vo.getFieldJavaType();

            // 设值
            DynformField field = new DynformField();
            field.setId(IdProvider.createUUIDId());
            field.setCreateBy(String.valueOf(currentUser.getId()));
            field.setCreateName(currentUser.getUsername());
            field.setCreateTime(now);
            //field.setSysOrgCode("");
            field.setIsValid(DBYNEnum.Y.name());
            field.setIsDelete(DBYNEnum.N.name());
            field.setTableId(head.getId());
            field.setFieldName(vo.getFieldName());
            field.setFieldComment(vo.getFieldComment());
            field.setFieldLength(BasicParserUtils.parseInt(vo.getPercision(), 0));
            field.setFieldPointLength(BasicParserUtils.parseInt(vo.getScale(), 0));
            field.setFieldDefault(vo.getFieldDefault());
            field.setFieldType(vo.getFieldDataType());
            field.setFieldIsPk(vo.getFieldIsPk());
            field.setFieldIsNull(vo.getFieldIsNull());
            field.setFieldOrder(BasicParserUtils.parseInt(vo.getFieldOrder(), 0));
            //field.setPageIsShow("");
            //field.setPageIsShowList("");
            //field.setPageShowType("");
            //field.setPageShowTypeLength(0);
            //field.setPageIsQuery("");
            //field.setPageMustInput("");
            //field.setValidType("");
            //field.setDictTable("");
            //field.setDictCode("");
            //field.setDictText("");
            //field.setOldFieldName("");
            field.setPageListColumnWidth(0);

            // 数据修正 =============================================================== S
            // 注释不存在
            if (StringUtils.isBlank(vo.getFieldComment())) {
                field.setFieldComment(vo.getFieldName());
            }

            // 类型修正
            if ("java.lang.Integer".equalsIgnoreCase(fieldJavaType)) {
                field.setFieldType("int");
            } else if ("java.lang.Long".equalsIgnoreCase(fieldJavaType)) {
                field.setFieldType("int");
            } else if ("java.util.Date".equalsIgnoreCase(fieldJavaType)) {
                field.setFieldType("Date");
                field.setPageShowType("date");
            } else if (!"java.lang.Double".equalsIgnoreCase(fieldJavaType) && !"java.lang.Float".equalsIgnoreCase(fieldJavaType)) {
                if (!"java.math.BigDecimal".equalsIgnoreCase(fieldJavaType) && !"BigDecimal".equalsIgnoreCase(fieldJavaType)) {
                    if (!"byte[]".equalsIgnoreCase(fieldJavaType) && !fieldJavaType.contains("blob")) {
                        if ("java.lang.Object".equals(fieldJavaType) && "text".equalsIgnoreCase(vo.getFieldDataType())) {
                            field.setFieldType("Text");
                            field.setPageShowType("textarea");
                        } else {
                            field.setFieldType("varchar");
                        }
                    } else {
                        field.setFieldType("Blob");
                    }
                } else {
                    field.setFieldType("BigDecimal");
                }
            } else {
                field.setFieldType("double");
            }

            // 长度修正
            if (StringUtils.isEmpty(vo.getPercision()) && StringUtils.isNotEmpty(vo.getCharMaxLength())) {
                if (Long.parseLong(vo.getCharMaxLength()) >= 3000L) {
                    field.setFieldType("Text");
                    field.setPageShowType("textarea");
                    try {
                        field.setFieldLength(Integer.valueOf(vo.getCharMaxLength()));
                    } catch (Exception var12) {
                        log.error(var12.getMessage(), var12);
                    }
                } else {
                    field.setFieldLength(Integer.valueOf(vo.getCharMaxLength()));
                }
            } else {
                if (StringUtils.isNotEmpty(vo.getPercision())) {
                    field.setFieldLength(Integer.valueOf(vo.getPercision()));
                } else if (field.getFieldType().equals("int")) {
                    field.setFieldLength(10);
                }

                if (StringUtils.isNotEmpty(vo.getScale())) {
                    field.setFieldPointLength(Integer.valueOf(vo.getScale()));
                }
            }

            // 数据修正 =============================================================== E

            //fields.add(field);

            this.dynformFieldMapper.insertSelective(field);
        }

        this.dynformHeadMapper.insertSelective(head);

        return UnifyResult.success();
    }

    private boolean excludeTableName(String tableName, String[] tableNamePrefixArr) {
        if (ArrayUtils.isEmpty(tableNamePrefixArr)) {
            return false;
        }
        for (String prefix : tableNamePrefixArr) {
            if (tableName.startsWith(prefix)) {
                return true;
            }
        }
        return false;
    }

    public DynformFieldDTO findExistsById(String fieldId, List<DynformFieldDTO> existsFields) {
        if (CollectionUtils.isEmpty(existsFields)) {
            return null;
        }
        for (DynformFieldDTO existsField : existsFields) {
            if (StringUtils.equals(fieldId, existsField.getId())) {
                return existsField;
            }
        }
        return null;
    }

    private List<DynformFieldDTO> getExistsFields(String tableId) {
        DynformFieldExample example = new DynformFieldExample();
        example.setOrderByClause("field_order ASC");
        example.createCriteria().andTableIdEqualTo(tableId);
        List<DynformField> dynformFields = dynformFieldMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(dynformFields)) {
            return new ArrayList<>();
        }

        List<DynformFieldDTO> list = new ArrayList<>();
        DynformFieldDTO tmp;
        for (DynformField dynformField : dynformFields) {
            tmp = new DynformFieldDTO();
            BeanUtils.copyProperties(dynformField, tmp);
            list.add(tmp);
        }
        return list;
    }

    private <T extends Default> UnifyResult checkTableFields(DynformHeadDTO dynformHeadDTO, Class<T> clazz) {
        String fields = dynformHeadDTO.getFields();
        if (StringUtils.isBlank(fields)) {
            return UnifyResult.success().setData(new ArrayList<>());
        }
        List<DynformFieldDTO> fieldList = JsonUtil.json2JavaBean(fields, new TypeToken<List<DynformFieldDTO>>() {
        }.getType());

        for (DynformFieldDTO dynformFieldDTO : fieldList) {
            // 字段名去除空白
            dynformFieldDTO.setFieldName(StringUtils.trimToEmpty(dynformFieldDTO.getFieldName()));

            // 验证参数
            UnifyResult validate = validateHelper.validate(dynformFieldDTO, clazz);
            if (UnifyResultUtil.isFail(validate)) {
                return validate;
            }
        }
        return UnifyResult.success().setData(fieldList);
    }

    private DynformHead selectByTableName(String tableName) {
        if (StringUtils.isBlank(tableName)) {
            return null;
        }

        DynformHeadExample example = new DynformHeadExample();
        example.createCriteria().andTableNameEqualTo(tableName);
        List<DynformHead> dynformHeads = dynformHeadMapper.selectByExample(example);

        if (CollectionUtils.isEmpty(dynformHeads)) {
            return null;
        }

        return dynformHeads.get(0);
    }

}
